package com.ijustyce.fastandroiddev.net;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;

import com.ijustyce.fastandroiddev.R;
import com.ijustyce.fastandroiddev.unit.LogCat;
import com.ijustyce.fastandroiddev.unit.ToastUnit;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.Map;

/**
 * Created by yc on 2015/8/12.
 */
public class NetWork {

    private static final String TAG = "NetWork";
    private static boolean showToast = true;

    /**
     * whether show ToastUnit , if in thread , please disable it
     *
     * @param value
     */
    public static void showToast(boolean value) {

        showToast = value;
    }

    private NetWork(){

    }

    /**
     * send a get request
     */
    public static synchronized boolean sendGet(Map<String, Object> map, String url, AsyncHttpResponseHandler listener, Context context) {

        Log.i("===add parameter===", "add");

        if (!isConnected(context)){
            return false;
        }
        RequestParams params = new RequestParams();
        if (map != null) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                if (null != value) {
                    params.put(key, value);
                }
            }
            map.clear();
        }
        HttpTask.get(url, params, listener);
        return true;
    }

    /**
     * send a post request
     */
    public static synchronized boolean sendPost(Map<String, Object> map, String url, AsyncHttpResponseHandler listener, Context context) {

        Log.i("===add parameter===", "add");

        if (!isConnected(context)){
            if (showToast){
                ToastUnit.showTop(R.string.error_network, context);
            }
            return false;
        }
        RequestParams params = new RequestParams();
        if (map != null) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                if (null != value) {
                    params.put(key, value);
                }
            }
            map.clear();
        }
        HttpTask.post(url, params, listener);
        return true;
    }

    /**
     * whether is connected to network .
     *
     * @return true if connect or return false
     */
    public static boolean isConnected(Context context) {

        if (context == null){
            if (showToast) {
                ToastUnit.showTop(R.string.error_network, context);
            }
            return false;
        }

        ConnectivityManager conManager = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = conManager.getActiveNetworkInfo();
        return networkInfo != null && networkInfo.isAvailable();
    }

    /**
     * whether is wifi
     * @param context
     * @return true if is wifi or return false
     */

    public static boolean isWifi(Context context){

        if (context == null){
            return false;
        }

        ConnectivityManager connectMgr = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo info = connectMgr.getActiveNetworkInfo();
        return info!=null && info.getType() == ConnectivityManager.TYPE_WIFI;
    }

    /**
     * upload file and pass parameter
     * @param url url to upload picture
     * @param param can be null , if you want to pass parameter and upload picture then add it
     * @param file file to upload
     * @param filePart filePart , ask developer of server interface please
     * @param context context , used to judge whether network is connect
     * @return
     */
    public static synchronized String uploadFile(String url, Map<String, String> param, File file, String filePart, Context context) {

        if (!isConnected(context)){
            return "false";
        }
        HttpPost post = new HttpPost(url);
        HttpClient client = new DefaultHttpClient();
        MultipartEntity entity = new MultipartEntity();
        if (param != null && !param.isEmpty()) {
            for (Map.Entry<String, String> entry : param.entrySet()) {
                try {
                    entity.addPart(entry.getKey(), new StringBody(entry.getValue()));
                }catch (UnsupportedEncodingException e){
                    LogCat.e(TAG, "upload file error: " + e.getMessage());
                }
            }
        }
        // 添加文件参数
        if (file != null && file.exists()) {
            entity.addPart(filePart, new FileBody(file));
        }

        HttpResponse response = null;
        post.setEntity(entity);
        try {
            response = client.execute(post);
        }catch (IOException e){
            LogCat.e(TAG , "upload file error: " + e.getMessage());
        }
        StatusLine status = response == null ? null : response.getStatusLine();
        if(status == null){
            return "false";
        }
        int stateCode = status.getStatusCode();
        StringBuilder sb = new StringBuilder();
        if (stateCode == HttpStatus.SC_OK) {
            HttpEntity result = response.getEntity();
            if (result != null) {
                try{
                    InputStream is = result.getContent();
                    BufferedReader br = new BufferedReader(
                            new InputStreamReader(is));
                    String tempLine;
                    while ((tempLine = br.readLine()) != null) {
                        sb.append(tempLine);
                    }
                    br.close();
                }catch (IOException e){
                    LogCat.e(TAG , "upload file error: " + e.getMessage());
                }
            }
        }
        post.abort();
        return sb.toString();
    }
}
